package com.siteseat.crudeq.broker.v1.request;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;

import com.siteseat.common.foundation.PropertyHelper;
import com.siteseat.crudeq.broker.netty.RequestHandler;
import com.siteseat.crudeq.broker.transport.BrokerSession;
import com.siteseat.crudeq.common.raw.protocol.v1.V1RequestId;

/**
 *
 */
public class V1RequestHandler extends V1AbstractRequestHandler {

  private RequestHandler loginHandler;

  private RequestHandler clickHandler;

  private RequestHandler publishBatchHandler;

  private RequestHandler historyHandler;
  
  private RequestHandler subscribeHandler;
  
  private RequestHandler unsubscribeHandler;
  
  private RequestHandler startWaitMessageHandler;
  
  private RequestHandler stopWaitMessageHandler;
  
  private RequestHandler disconnectHandler;
  
  /**
   * {@inheritDoc}
   */
  @Override
  protected void doInit() throws Exception {
    super.doInit();
    
    PropertyHelper.ensureInitialized( log, getLoginHandler(), "loginHandler" );
    PropertyHelper.ensureInitialized( log, getClickHandler(), "clickHandler" );
    //PropertyHelper.ensureInitialized( log, getPublishBatchHandler(), "publishBatchHandler" );
    PropertyHelper.ensureInitialized( log, getHistoryHandler(), "historyHandler" );
    PropertyHelper.ensureInitialized( log, getSubscribeHandler(), "subscribeHandler" );
    PropertyHelper.ensureInitialized( log, getUnsubscribeHandler(), "unsubscribeHandler" );
    PropertyHelper.ensureInitialized( log, getStartWaitMessageHandler(), "startWaitMessageHandler" );
    PropertyHelper.ensureInitialized( log, getStopWaitMessageHandler(), "stopWaitMessageHandler" );
    PropertyHelper.ensureInitialized( log, getDisconnectHandler(), "disconnectHandler" );
  }

  /**
   * Gets the startWaitMessageHandler
   *
   * @return the startWaitMessageHandler
   */
  public RequestHandler getStartWaitMessageHandler() {
    return startWaitMessageHandler;
  }

  /**
   * Sets the startWaitMessageHandler
   *
   * @param startWaitMessageHandler the startWaitMessageHandler to set
   */
  public void setStartWaitMessageHandler( RequestHandler startWaitMessageHandler ) {
    this.startWaitMessageHandler = startWaitMessageHandler;
  }

  /**
   * Gets the disconnectHandler
   *
   * @return the disconnectHandler
   */
  public RequestHandler getDisconnectHandler() {
    return disconnectHandler;
  }

  /**
   * Sets the disconnectHandler
   *
   * @param disconnectHandler the disconnectHandler to set
   */
  public void setDisconnectHandler( RequestHandler disconnectHandler ) {
    this.disconnectHandler = disconnectHandler;
  }

  /**
   * Gets the stopWaitMessageHandler
   *
   * @return the stopWaitMessageHandler
   */
  public RequestHandler getStopWaitMessageHandler() {
    return stopWaitMessageHandler;
  }

  /**
   * Sets the stopWaitMessageHandler
   *
   * @param stopWaitMessageHandler the stopWaitMessageHandler to set
   */
  public void setStopWaitMessageHandler( RequestHandler stopWaitMessageHandler ) {
    this.stopWaitMessageHandler = stopWaitMessageHandler;
  }

  /**
   * Gets the unsubscribeHandler
   *
   * @return the unsubscribeHandler
   */
  public RequestHandler getUnsubscribeHandler() {
    return unsubscribeHandler;
  }

  /**
   * Sets the unsubscribeHandler
   *
   * @param unsubscribeHandler the unsubscribeHandler to set
   */
  public void setUnsubscribeHandler( RequestHandler unsubscribeHandler ) {
    this.unsubscribeHandler = unsubscribeHandler;
  }

  /**
   * Gets the subscribeHandler
   *
   * @return the subscribeHandler
   */
  public RequestHandler getSubscribeHandler() {
    return subscribeHandler;
  }



  /**
   * Sets the subscribeHandler
   *
   * @param subscribeHandler the subscribeHandler to set
   */
  public void setSubscribeHandler( RequestHandler subscribeHandler ) {
    this.subscribeHandler = subscribeHandler;
  }



  /**
   * Gets the loginHandler
   *
   * @return the loginHandler
   */
  public RequestHandler getLoginHandler() {
    return loginHandler;
  }

  /**
   * Sets the loginHandler
   *
   * @param loginHandler the loginHandler to set
   */
  public void setLoginHandler( RequestHandler loginHandler ) {
    this.loginHandler = loginHandler;
  }

  /**
   * Gets the clickHandler
   *
   * @return the clickHandler
   */
  public RequestHandler getClickHandler() {
    return clickHandler;
  }

  /**
   * Sets the clickHandler
   *
   * @param clickHandler the clickHandler to set
   */
  public void setClickHandler( RequestHandler clickHandler ) {
    this.clickHandler = clickHandler;
  }
  

  /**
   * Gets the publishBatchHandler
   *
   * @return the publishBatchHandler
   */
  public RequestHandler getPublishBatchHandler() {
    return publishBatchHandler;
  }

  /**
   * Sets the publishBatchHandler
   *
   * @param publishBatchHandler the publishBatchHandler to set
   */
  public void setPublishBatchHandler( RequestHandler publishBatchHandler ) {
    this.publishBatchHandler = publishBatchHandler;
  }

  /**
   * Gets the historyHandler
   *
   * @return the historyHandler
   */
  public RequestHandler getHistoryHandler() {
    return historyHandler;
  }

  /**
   * Sets the historyHandler
   *
   * @param historyHandler the historyHandler to set
   */
  public void setHistoryHandler( RequestHandler historyHandler ) {
    this.historyHandler = historyHandler;
  }

  /**
   * @param session
   * @param reqId
   * @param ch
   * @param input
   * @throws Exception
   */
  public void execute( BrokerSession session, byte reqId, Channel ch, ChannelBuffer input, short version )
          throws Exception {
    RequestHandler h = findDedicatedHandler( session, ch, reqId );
    // how to handle null ?
    h.execute( session, reqId, ch, input, version );
  }

  public RequestHandler findDedicatedHandler( BrokerSession session, Channel ch, byte reqId ) throws Exception {
    RequestHandler h;

    switch( reqId ) {
      case V1RequestId.LOGIN:               h = getLoginHandler();                          break;
      case V1RequestId.CLICK:               h = getClickHandler();                          break;
      case V1RequestId.PUBLISH_BATCH:       h = getPublishBatchHandler();                   break;
      case V1RequestId.HISTORY:             h = getHistoryHandler();                        break;
      case V1RequestId.SUBSCRIBE:           h = getSubscribeHandler();                      break;
      case V1RequestId.UNSUBSCRIBE:         h = getUnsubscribeHandler();                    break;
      case V1RequestId.START_WAIT_MESSAGE:  h = getStartWaitMessageHandler();               break;
      case V1RequestId.STOP_WAIT_MESSAGE:   h = getStopWaitMessageHandler();                break;
      case V1RequestId.DISCONNECT:          h = getDisconnectHandler();                     break;
      default:                              writeAndLogInvalidRequestError( ch, session );  return null;
    }

    return h;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean needAuthentication( BrokerSession session, Channel ch, ChannelBuffer input, byte reqId )
          throws Exception {
    RequestHandler r = findDedicatedHandler( session, ch, reqId );
    // how to handle null ?
    return r.needAuthentication( session, ch, input, reqId );
  }

}
